import {
  ChangeEvent,
  useRef,
  useEffect,
  useState,
} from "react";
import useMergeState from "./utils/useMergeState";

// 非受控模式  onChange
function AppOnchange() {
  function onChange(event: ChangeEvent<HTMLInputElement>) {
    console.log(event.target.value);
  }

  return <input defaultValue={"123"} onChange={onChange} />;
}

// 非受控模式 ref
function AppRef() {
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    setTimeout(() => {
      console.log(inputRef.current?.value);
    }, 2000);
  }, []);

  return <input defaultValue={"123"} ref={inputRef} />;
}

// 受控模式 useState
function AppUseSate() {
  const [value, setValue] = useState("123");

  function onChange(event: ChangeEvent<HTMLInputElement>) {
    console.log(event.target.value);
    setValue(event.target.value.toUpperCase());
  }
  return <input value={value} onChange={onChange} />;
}

interface CalendarPropsNO {
  defaultValue?: Date;
  onChange?: (date: Date) => void;
}

// 非受控 Calendar
function CalendarNO(props: CalendarPropsNO) {
  const { defaultValue, onChange } = props;

  const [value, setValue] = useState(defaultValue);

  function changeValue(date: Date) {
    setValue(date);
    onChange?.(date);
  }

  return (
    <div>
      {value?.toLocaleDateString()}
      <div
        onClick={() => {
          changeValue(new Date("2024-5-1"));
        }}
      >
        2023-5-1
      </div>
      <div
        onClick={() => {
          changeValue(new Date("2024-5-2"));
        }}
      >
        2023-5-2
      </div>
      <div
        onClick={() => {
          changeValue(new Date("2024-5-3"));
        }}
      >
        2023-5-3
      </div>
    </div>
  );
}

interface CalendarPropsYES {
  value: Date;
  onChange?: (date: Date) => void;
}

// 受控模式 Calendar
function CalendarYES(props: CalendarPropsYES) {
  const { value, onChange } = props;

  function changeValue(date: Date) {
    onChange?.(date);
  }
  return (
    <div>
      {value.toLocaleDateString()}
      <div
        onClick={() => {
          changeValue(new Date("2024-5-1"));
        }}
      >
        2023-5-1
      </div>
      <div
        onClick={() => {
          changeValue(new Date("2024-5-2"));
        }}
      >
        2023-5-2
      </div>
      <div
        onClick={() => {
          changeValue(new Date("2024-5-3"));
        }}
      >
        2023-5-3
      </div>
    </div>
  );
}

interface CalendarProps {
  value?: Date;
  defaultValue?: Date;
  onChange?: (date: Date) => void;
}
// 同时支持受控模式和非受控模式
function CalendarInnter(props: CalendarProps) {
  const {
    value: propsValue,
    defaultValue,
    onChange,
  } = props;

  const [value, setValue] = useState(defaultValue);

  const isFirstRender = useRef(true);

  // 外部改变内部
  useEffect(() => {
    if (propsValue == undefined && !isFirstRender.current) {
      setValue(propsValue);
    }
    isFirstRender.current = false;
  }, [propsValue]);

  // 合并内外部
  const mergedValue =
    propsValue === undefined ? value : propsValue;

  // 修改内外部
  function changeValue(date: Date) {
    if (propsValue === undefined) {
      setValue(date);
    }
    onChange?.(date);
  }

  return (
    <div>
      {mergedValue?.toLocaleDateString()}
      <div
        onClick={() => {
          changeValue(new Date("2024-5-1"));
        }}
      >
        2023-5-1
      </div>
      <div
        onClick={() => {
          changeValue(new Date("2024-5-2"));
        }}
      >
        2023-5-2
      </div>
      <div
        onClick={() => {
          changeValue(new Date("2024-5-3"));
        }}
      >
        2023-5-3
      </div>
    </div>
  );
}

function Calendar(props: CalendarProps) {
  const { value, defaultValue, onChange } = props;
  const [mergedValue, setValue] = useMergeState(
    new Date(),
    {
      defaultValue,
      value,
      onChange,
    }
  );

  return (
    <div>
      {mergedValue?.toLocaleDateString()}
      <div
        onClick={() => {
          setValue(new Date("2024-5-1"));
        }}
      >
        2023-5-1
      </div>
      <div
        onClick={() => {
          setValue(new Date("2024-5-2"));
        }}
      >
        2023-5-2
      </div>
      <div
        onClick={() => {
          setValue(new Date("2024-5-3"));
        }}
      >
        2023-5-3
      </div>
    </div>
  );
}

function App() {
  const [value, setValue] = useState(
    new Date("2025-04-14")
  );
  return (
    <Calendar
      // value={value}
      // onChange={(date) => {
      //   // setValue(date);
      // }}
    />
  );
}

export default App;
